package com.wangyadong.hobby.schedule.jobtask.teststack.test.map;

import com.wangyadong.hobby.schedule.jobtask.tree.pq.Entry;

import java.util.Iterator;
import java.util.function.Consumer;

/**
 * <p>
 *
 * @author <714037465@qq.com>
 * @since 2018/9/2612:54
 **/
public abstract class AbstractMap<K, V> implements Map<K, V> {

    private class KeyIterator implements Iterator<K> {
        private Iterator<Entry<K, V>> entries = entrySet().iterator(); // reuse entrySet

        public void remove() {
            throw new UnsupportedOperationException();
        }

        public boolean hasNext() {
            return entries.hasNext();
        }

        public K next() {
            return entries.next().getKey();
        }
    }

    private class KeyIteratable implements Iterable {
        public Iterator<K> iterator() {
            return new KeyIterator();
        }
    }

    private class VlaueIterator implements Iterator<V> {
        private Iterator<Entry<K, V>> entry = entrySet().iterator();

        public void remove() {
            throw new UnsupportedOperationException();
        }

        public boolean hasNext() {
            return entry.hasNext();
        }

        public V next() {
            return entry.next().getValue();
        }
    }

    private class ValueIterable implements Iterable<V> {
        public Iterator<V> iterator() {
            return new VlaueIterator();
        }
    }

    public Iterable values() {
        return new ValueIterable();
    }

    public Iterable keySet() {
        return new KeyIteratable();
    }

    @Override
    public int size() {
        return size();
    }

    @Override
    public boolean isEmpty() {
        return size() == 0;
    }


    protected static class MapEntry<K, V> implements Entry<K, V> {
        private K key;
        private V value;

        public MapEntry(K k, V v) {
            key = k;
            value = v;
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        public void setKey(K key) {
            key = key;
        }

        public V setValue(V v) {
            V older = this.value;
            value = v;
            return older;
        }
    }


}
